package cn.anc.aonicardv.module.ui.recorder;

import android.annotation.TargetApi;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkRequest;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.TextView;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.List;

import butterknife.BindView;
import butterknife.OnClick;
import cn.anc.aonicardv.Configs;
import cn.anc.aonicardv.Constant;
import cn.anc.aonicardv.MyApplication;
import cn.anc.aonicardv.R;
import cn.anc.aonicardv.R2;
import cn.anc.aonicardv.bean.RecorderConnectListBean;
import cn.anc.aonicardv.event.RequestMobileNetworkEvent;
import cn.anc.aonicardv.event.UpdateWifiName;
import cn.anc.aonicardv.module.ui.base.BaseFragment;
import cn.anc.aonicardv.module.ui.my.SettingActivity;
import cn.anc.aonicardv.param.ParamManager;
import cn.anc.aonicardv.util.ActivityUtils;
import cn.anc.aonicardv.util.AoniRecorderInfoUtils;
import cn.anc.aonicardv.util.DialogUtils;
import cn.anc.aonicardv.util.GpsUtil;
import cn.anc.aonicardv.util.LogUtil;
import cn.anc.aonicardv.util.NetUtils;
import cn.anc.aonicardv.util.SpUtils;
import cn.anc.aonicardv.util.StringUtils;
import cn.anc.aonicardv.util.UIUtil;
import cn.anc.aonicardv.util.ui.IpUtil;
import cn.anc.aonicardv.util.ui.UiTool;
import cn.anc.aonicardv.widget.ConnectRecorderWifiDialog;
import cn.anc.httpcontrolutil.CarControl;
import cn.anc.httpcontrolutil.CarControlCommand;
import cn.anc.httpcontrolutil.CarControlSettings;
import cn.anc.httpcontrolutil.SocketUtils;

import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;


/**
 * Created by yangdai on 2017/5/16.
 */

public class RecorderFragment extends BaseFragment implements CarControl.OnHeartBeatCallBack, View.OnClickListener, CarControl.OnCarControlCallback {

    public static final String TYPE_NORMAL = "type_normal";
    public static final String TYPE_EVENT = "type_event";
    @BindView(R2.id.tv_enter_recorder)
    TextView enterRecorderTv;
    @BindView(R2.id.tv_connect_wifi_name)
    TextView connectWifiNameTv;
    @BindView(R2.id.tv_back)
    TextView backTv;

    @BindView(R2.id.tv_title)
    TextView titleTv;

    @BindView(R2.id.tv_right_image2)
    ImageView rightTv2;
    @BindView(R2.id.tv_progress)
    TextView progressTv;
    @BindView(R2.id.tv_big_product_image)
    TextView bigProductImageTv;
    private boolean isConnecting;
    private boolean isPause;
    private ConnectivityManager connectivityManager;
    //因为在mainActivity界面监听wifi，只要onResume就会获取一次。增加一个变量控制当当前ssid一致时，不自动进入
    private String currentSSID;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return initView(R.layout.fragment_recorder);
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EventBus.getDefault().register(this);

    }

    @Override
    public void initVariable() {
        connectivityManager = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
        dialogUtils = new DialogUtils();
    }

    private boolean isTimeOut = false;
    private final int MSG_CONNECT_TIME_OUT = 522;
    private int timeOut = 0;
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_CONNECT_TIME_OUT:
                    timeOut++;
                    //设置超时时间为5秒
                    if (isConnecting && timeOut >= 10) {
                        isTimeOut = true;
                        stopConnectAnimation();
                        UiTool.showToast(getContext(), R.string.tip_cardv_connect_fail);
                    } else {
                        sendEmptyMessageDelayed(MSG_CONNECT_TIME_OUT, 1000);
                    }
                    break;
                default:
                    break;
            }

            super.handleMessage(msg);
        }
    };

    @Override
    public void findViewById(View view) {
    }

    @Override
    public void setListener() {
        UIUtil.setProductDefaultImage(Configs.DEFUTL_SHOW_IMAGE, bigProductImageTv);
        enterRecorderTv.setOnClickListener(this);
        rightTv2.setOnClickListener(this);
    }

    @Override
    public void onResume() {
        super.onResume();
        CarControl.setOnHeartBeatCallBack(this);
        updateRecorderConnectStatus();
        if (!CarControl.IsConnected.get())
            enterRecorderTv.setText(getString(R.string.connect_recorder));
        else
            enterRecorderTv.setText(getString(R.string.enter_recorder));
        isPause = false;
        setProductImageByModel();

    }

    private ProgressDialog progressDialog;

    private void initProgressDialog() {
        progressDialog = new ProgressDialog(getActivity());
        progressDialog.setIndeterminate(false);//循环滚动
        progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        progressDialog.setMessage("loading...");
        progressDialog.setCancelable(false);//false不能取消显示，true可以取消显示
    }

    @Override
    public void onPause() {
        super.onPause();
        isPause = true;
    }

    private void updateRecorderConnectStatus() {
        setCurrentWifiName();
        if (CarControl.IsConnected.get()) {
            connectWifiNameTv.setTextColor(getResources().getColor(R.color.textColor4));
            Drawable drawable = getResources().getDrawable(R.mipmap.connected_icon);
            drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
            connectWifiNameTv.setCompoundDrawables(null, null, drawable, null);
        } else {
            connectWifiNameTv.setTextColor(Color.RED);
            Drawable drawable = getResources().getDrawable(R.mipmap.no_connect_icon);
            drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
            connectWifiNameTv.setCompoundDrawables(null, null, drawable, null);
        }
    }

    @Override
    public void initData() {
        titleTv.setText(getString(R.string.recorder));
        rightTv2.setVisibility(View.VISIBLE);
        rightTv2.setImageResource(R.mipmap.setting);
        backTv.setVisibility(View.GONE);

    }

    private void setProductImageByModel() {

        String temp = SpUtils.getString(Constant.SpKeyParam.RECORDER_CONNECT_LIST, null);
        if (temp != null) {
            List<RecorderConnectListBean> recorderConnectListBeanList = new Gson().fromJson(temp, new TypeToken<List<RecorderConnectListBean>>() {
            }.getType());
            for (int i = 0; i < recorderConnectListBeanList.size(); i++) {
                if (recorderConnectListBeanList.get(i).isLast()) {
                    recorderConnectListBeanList.get(i).setProductImage(bigProductImageTv, true);
                }
            }
        }
    }

    @OnClick(R2.id.tv_back)
    public void back() {
        getActivity().finish();
    }

    private void connectCurrentWifiFromRecorderList() {
        //这里做一个判断  自动连接判断
        if (!getConnectStatus())
            return;
        if (null == currentSSID || !currentSSID.equals(MyApplication.wifiSSID)) {
            currentSSID = MyApplication.wifiSSID;
            if (!isConnecting) {
                isConnecting = true;
                enterRecorder();
                requestNetwork();
            }
        }
        String temp = SpUtils.getString(Constant.SpKeyParam.RECORDER_CONNECT_LIST, null);
        if (!TextUtils.isEmpty(temp)) {
            List<RecorderConnectListBean> recorderConnectListBeanList = new Gson().fromJson(temp, new TypeToken<List<RecorderConnectListBean>>() {
            }.getType());
            for (int i = 0; i < recorderConnectListBeanList.size(); i++) {
                RecorderConnectListBean recorderConnectRecordBean = recorderConnectListBeanList.get(i);
                if (MyApplication.wifiSSID != null && MyApplication.wifiSSID.equals(recorderConnectRecordBean.getWifiSSID()) && !CarControl.IsConnected.get() && !isConnecting) {
                    if (null == currentSSID || !currentSSID.equals(MyApplication.wifiSSID)) {
                        currentSSID = MyApplication.wifiSSID;
                        if (!isPause && !isConnecting) {
                            isConnecting = true;
                            enterRecorder();
                            requestNetwork();
                        }
                    }
                }
            }
        }
    }
    private void requestNetwork() {
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
            checkNetworkAvailable();
            forceSendRequestByMobileData();
        }
    }
    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        updateRecorderConnectStatus();
    }

    /**
     * 判断是wifi直连返回值   并做出相对应处理，四种情况
     * <p>
     * 1.当传统wifi未连接，wifi直连连接。使用wifi直连
     * 2.当传统wifi连接，wifi直连未连接  使用传统wifi
     * 3.当传统wifi连接其他非记录仪ip wifi，wifi直连连接记录仪，使用wifi直连
     * 4.当传统wifi连接记录仪，wifi直连也连接记录仪时，使用传统wifi记录仪
     *
     * @param event
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(UpdateWifiName event) {
        String wifiIp = IpUtil.getContainsIp(NetUtils.getWifiIpAddress(getContext()));
        //获取当前手机wifi，当手机传统wifi获取到的ip为记录仪Ip时，只使用传统记录仪wifi
        if (!StringUtils.isEmptyOrNull(wifiIp)) {
            if (!event.isWifiP2P) {
                if (null != connectRecorderWifiDialog && connectRecorderWifiDialog.isShowing()) {
                    connectRecorderWifiDialog.dismiss();
                }
                MyApplication.wifiSSID = event.devicesName;
                MyApplication.IPHeader = IpUtil.getContainsIp(event.deviceIp);
                MyApplication.IP = IpUtil.getContainsIp(event.deviceIp) + "1";
                CarControl.setParam(MyApplication.IP, ParamManager.CarServerParam.CarControlHttpPort);
                CarControl.setDataParam(MyApplication.IP, ParamManager.CarServerParam.CarControlDataPort);
                updateRecorderConnectStatus();
                if (event.isReceiver) {
                    currentSSID = null;
                    if (!isPause)
                        connectCurrentWifiFromRecorderList();
                } else {
                    connectCurrentWifiFromRecorderList();
                }

            }
        } else {
            if (event.isWifiP2P) {
                MyApplication.wifiSSID = event.devicesName;
                MyApplication.IPHeader = IpUtil.getContainsIp(event.deviceIp);
                MyApplication.IP = IpUtil.getContainsIp(event.deviceIp) + "1";
                CarControl.setParam(MyApplication.IP, ParamManager.CarServerParam.CarControlHttpPort);
                CarControl.setDataParam(MyApplication.IP, ParamManager.CarServerParam.CarControlDataPort);
            }
        }

    }

    private ConnectRecorderWifiDialog connectRecorderWifiDialog;

    @Override
    public void onClick(View v) {
        int i = v.getId();
        if (i == R.id.tv_enter_recorder) {
            if (!getConnectStatus()) {
                connectRecorderWifiDialog = new ConnectRecorderWifiDialog(getContext(), R.style.BaseDialogStyle);
                connectRecorderWifiDialog.show();
            } else {
                if (!isConnecting) {
                    isConnecting = true;
                    requestNetwork();
                    enterRecorder();
                }
            }
        } else if (i == R.id.tv_right_image2) {
            ActivityUtils.jumpActivity(getActivity(), SettingActivity.class);
        }
    }

    private DialogUtils dialogUtils;

    private void showGpsDialog() {
        dialogUtils.getCustomMessageAlertDialog(getActivity(), R.string.location_authorization_alert).setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        }).setPositiveButton(getString(R.string.discount), new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                startActivityForResult(intent, 0); // 设置完成后返回到原来的界面
            }
        }).show();
    }

    //判断是否可以连接   ---连接必然条件  ssid不能为空，ssid相对应的开头   IPHeader不能为空  ip不能为空
    private boolean getConnectStatus() {
        return MyApplication.IP != null && MyApplication.IPHeader != null && MyApplication.wifiSSID != null && NetUtils.getWifiIpAddress(getContext()).startsWith(MyApplication.IPHeader);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(RequestMobileNetworkEvent event) {
        forceSendRequestByMobileData();
    }

    private void setCurrentWifiName() {
        connectWifiNameTv.setText("");
        if (MyApplication.IPHeader != null && MyApplication.wifiSSID != null
                && CarControl.IsConnected.get()
        ) {
            connectWifiNameTv.setText(MyApplication.wifiSSID);
        } else {
            connectWifiNameTv.setText(R.string.recorder_no_connect_hint);
        }
    }

    @Override
    public void OnHeartBeatConnectOK() {
        CarControl.doGetDeviceConnectInfo("1", this);
    }

    private void setConnectBtnEnable(boolean enable) {
        if (null != enterRecorderTv) {
            if (enable) {
                enterRecorderTv.setEnabled(true);
            } else {
                enterRecorderTv.setEnabled(false);
            }
        }

    }

    @Override
    public void OnHeartBeatConnectFail() {
        stopConnectAnimation();
        UiTool.showToast(getContext(), R.string.tip_cardv_connect_fail);
    }

    @Override
    public void OnHeartBeatDisconnect() {
        stopConnectAnimation();
    }


    private void startConnectAnimation() {
        isTimeOut = false;
        timeOut = 0;
        handler.post(new Runnable() {
            @Override
            public void run() {
                setConnectBtnEnable(false);
                progressTv.setVisibility(View.VISIBLE);
                progressTv.clearAnimation();
                Animation animation = AnimationUtils.loadAnimation(getContext(), R.anim.recorder_connect_progress);
                progressTv.startAnimation(animation);
            }
        });

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        currentSSID = null;
        EventBus.getDefault().unregister(this);
    }

    @Override
    public void OnCommandCallback(int code, CarControl.CommandResponseInfo info) {
        if (code != 0)
            return;
        switch (info.msg_id) {
            case CarControlCommand.CAR_CONTROL_COMMAND_ID_GET_DEVICE_INFO:
                SpUtils.putBoolean(Constant.SpKeyParam.IS_SETT_TIME_OF_MANUAL,false);
                CarControlSettings.initGuiResource();
                stopConnectAnimation();
                startActivityOfTime();
                AoniRecorderInfoUtils.saveConnectedRecorderInfo(MyApplication.wifiSSID, MyApplication.wifiPassword, CarControl.DeviceInfo.model);
                CarControl.doGetWifiPassword(this);
                break;
            case CarControlCommand.CAR_CONTROL_COMMAND_GET_WIFI_PASSWORD:
                if (info.param != null) {
                    MyApplication.wifiPassword = info.param;
                }
                AoniRecorderInfoUtils.modifyConnectedRecorderInfo(MyApplication.wifiSSID, "wifiPassword", MyApplication.wifiPassword);
                break;

            case CarControlCommand.CAR_CONTROL_COMMAND_ID_GET_DEVICE_CONNECT_INFO:
                LogUtil.e("llcDebug", "------------收到获取到的记录仪连接信息--:" + info.toString());
                if (info.rval != -1) {
                    CarControl.doGetDeviceInfo(this);
                }
                break;
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    private void checkNetworkAvailable() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M || SocketUtils.wifiNetwork != null) {
            return;
        }
        try {
            NetworkRequest localNetworkRequest = new NetworkRequest.Builder().removeCapability(NET_CAPABILITY_INTERNET).addTransportType(TRANSPORT_WIFI).build();
            ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() {
                @Override
                public void onAvailable(Network network) {
                    super.onAvailable(network);
                    try {
                        SocketUtils.setWifiNetwork(network);
                        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
                            ConnectivityManager.setProcessDefaultNetwork(network);
                        }
                    } catch (Exception ex) {
                    }
                }

                @Override
                public void onLost(Network network) {
                    super.onLost(network);
                    SocketUtils.setWifiNetwork(null);
                }

            };
            connectivityManager.requestNetwork(localNetworkRequest, networkCallback);
        } catch (Exception e) {
        }
    }

    @TargetApi(Build.VERSION_CODES.M)
    private void forceSendRequestByMobileData() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            LogUtil.e("llcTest", "-----------------:forceSendRequestByMobileData");
            try {
                NetworkRequest.Builder builder = new NetworkRequest.Builder();
                builder.addCapability(NET_CAPABILITY_INTERNET);
                builder.addTransportType(TRANSPORT_CELLULAR);
                NetworkRequest networkRequest = builder.build();
                ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() {
                    @Override
                    public void onAvailable(Network network) {
                        super.onAvailable(network);
                        SocketUtils.setMobileNetWork(network);
                        if (Build.VERSION.SDK_INT >= 23) {
                            connectivityManager.bindProcessToNetwork(network);
                        } else {
                            // 23后这个方法舍弃了
                            ConnectivityManager.setProcessDefaultNetwork(network);
                        }
                    }

                    @Override
                    public void onLost(Network network) {
                        super.onLost(network);
                        SocketUtils.setMobileNetWork(null);
                        connectivityManager.unregisterNetworkCallback(this);

                    }
                };
                connectivityManager.requestNetwork(networkRequest, networkCallback);
            } catch (Exception e) {

            }
        }
    }

    private void enterRecorder() {
        startConnectAnimation();
        delayEnterRecorder();
    }

    private void delayEnterRecorder() {
        handler.sendEmptyMessage(MSG_CONNECT_TIME_OUT);
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (CarControl.IsConnected.get()) {
                    stopConnectAnimation();
                    startActivityOfTime();

                } else {
                    CarControl.HeartBeatStart(MyApplication.IP, ParamManager.CarServerParam.CarControlNotifyPort, "hi", "car");
                }
            }
        }, 800);
    }


    private void stopConnectAnimation() {
        timeOut = 0;
        isConnecting = false;
        handler.removeMessages(MSG_CONNECT_TIME_OUT);
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (null != progressTv) {
                    progressTv.clearAnimation();
                    progressTv.setVisibility(View.GONE);
                }
                setConnectBtnEnable(true);
            }
        });

    }

    private static final int MIN_DELAY_TIME = 2000;  // 两次间隔不能少于2000ms
    private static long lastClickTime;

    public void startActivityOfTime() {
        long currentClickTime = System.currentTimeMillis();
        if (!isTimeOut && (currentClickTime - lastClickTime) >= MIN_DELAY_TIME) {
            lastClickTime = currentClickTime;
//            if (IpUtil.isHuaweiChip(CarControl.DeviceInfo.model)) {
//                ActivityUtils.jumpActivity(getActivity(), RecorderHicamActivity.class);
//            } else {
            ActivityUtils.jumpActivity(getActivity(), RecorderActivity.class);
//            }
        }

    }

}

